/**
 * Copyright @ 2023 iAuto (Shanghai) Co., Ltd.
 * All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are NOT permitted except as agreed by
 * iAuto (Shanghai) Co., Ltd.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 */
interface Block {
  opcode: string;
  next: string | null;
  parent: string | null;
  inputs: Record<string, [number, string | [number, string]]>;
  fields: Record<string, [string, null]>;
  shadow: boolean;
  topLevel: boolean;
  x?: number;
  y?: number;
}
interface SceneData {
  [key: string]: Block;
}

// interface TopLevelBlock extends Block {
//   children: Record<string, Block>;
// }

// 定义 separateBlocks 函数
function separateBlocks(nodeId: string, data: SceneData, separatedBlocks: Record<string, Block>) {
  const node = data[nodeId];
  if (!node) return;

  // 将当前块存储在 separatedBlocks 中
  separatedBlocks[nodeId] = node;

  // 如果块有下一个节点，继续递归
  if (node.next) {
    separateBlocks(node.next, data, separatedBlocks);
  }

  // 如果块有子块（例如，SUBSTACK），也递归处理它们
  if (node.inputs) {
    Object.keys(node.inputs).forEach((key) => {
      const substackId = node.inputs[key][1];
      if (typeof substackId === 'string') {
        separateBlocks(substackId, data, separatedBlocks);
      }
    });
  }
}

// 分离场景数据 按照块进行区分
export function separateAndGroupBlocks(jsonData: SceneData): Record<string, Block> {
  const topLevelBlocks: Record<string, Block> = {};

  // 遍历 JSON 数据，找到所有顶级块并分离它们及其后代块
  for (const key in jsonData) {
    const node = jsonData[key];

    if (node.topLevel && node.opcode === 'control_when') {
      // 创建一个空对象，用于存储分离后的块
      // const separatedBlocks: Record<string, Block> = {};
      // 收集对应的块内容
      separateBlocks(key, jsonData, topLevelBlocks);
      break;
      // 放到顶层数据里面
      // topLevelBlocks = separatedBlocks;
    }
  }

  return topLevelBlocks;
}

// 查找指定 opcode 的 key
export const findOpcodeKey = (opcode: string, jsonData: SceneData): string => {
  let opcodeKey = '';
  for (const key in jsonData) {
    const node = jsonData[key];
    if (node.opcode === opcode) {
      opcodeKey = key;
      break;
    }
  }
  return opcodeKey;
};

// 获取 主场景数据 分离 退出场景 和 其他场景数据
export function separateBlocksByKey(jsonData: SceneData) {
  // 收集场景数据
  const separateBlockList: Record<string, Block>[] = [];

  // 读取主场景数据
  const groupBlocks = separateAndGroupBlocks(jsonData);

  // 查找退出条件的key
  const exitKey = findOpcodeKey('control_exit', groupBlocks);

  // 创建一个空对象，用于存储分离后的块
  const separatedBlocks: Record<string, Block> = {};
  // 收集 退出场景数据
  separateBlocks(exitKey, groupBlocks, separatedBlocks);

  // 收集其他场景数据
  const otherBlocks = {};
  for (const key in groupBlocks) {
    const node = groupBlocks[key];
    // 不存在于指定数据的块收集起来
    if (!separatedBlocks[key]) {
      otherBlocks[key] = node;
    }
  }

  // 收集主场景数据
  separateBlockList.push(otherBlocks);
  if (exitKey) {
    // 收集退出场景数据
    separateBlockList.push(separatedBlocks);
  }
  return { separateBlockList, groupBlocks };
}
